package com.blog.service.Impl;
import com.alibaba.fastjson.JSON;
import com.blog.Event.EventMsgDomain;
import com.blog.SystemMsg.SystemMsgProducer;
import com.blog.Utils.ConsetUtils;
import com.blog.Utils.RedisKeyUtil;
import com.blog.bean.domain.Comment;
import com.blog.bean.domain.DiscussPost;
import com.blog.bean.domain.User;
import com.blog.mapper.CommentMapper;
import com.blog.mapper.DiscussPostMapper;
import com.blog.mapper.UserMapper;
import com.blog.service.CommentService;
import com.blog.service.LikeService;
import com.blog.bean.vo.CommentAndPost;
import com.blog.bean.vo.CommentVO;
import com.blog.bean.vo.LikeVO;
import com.blog.bean.vo.PostAndCommentVO;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author 任浩
 * @version 1.0
 */

@Service
@Slf4j
public class CommentServiceImpl implements CommentService {

    @Autowired
    private CommentMapper commentMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private DiscussPostMapper discussPostMapper;
    @Autowired
    private LikeService likeService;
    @Autowired
    private SystemMsgProducer systemMsgProducer;
    @Autowired
    private EventMsgDomain eventMsgDomain;
    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 查询帖子的楼主评论
     * @param comment
     * @return
     */
    @Override
    public PostAndCommentVO queryComment(Comment comment, Integer curpage, Integer pageNum,Integer userId) {
        //开启分页查询
        PageHelper.startPage(curpage,pageNum);
        System.out.println(comment);
        Page<Comment> page = commentMapper.queryComment(comment);
        //得到分页的内容
        List<Comment> result = page.getResult();
        List<Map<String,Object>> commentListVO = new ArrayList<>();

        //进行查询楼主评论下的回复
        for(Comment con : result){
            Map<String , Object > map = new HashMap<>();
            Comment replyCommen = new Comment();
            replyCommen.setEntityType(ConsetUtils.ENTITY_TYPE_REPLY);
            replyCommen.setEntityId(comment.getEntityId());
            replyCommen.setStatus(con.getId());  //通过设置当前值来设置，获取当前评论下的回复
            //得到所有回复。
            List<Comment> replyComments = commentMapper.queryReply(replyCommen);
            List<Map<String,Object>> replyCommentsVO = new ArrayList<>();
            //根据评论回复的id，我们要查找到所有用户的名字。
            for(Comment c : replyComments){
                Map<String,Object> map1 =new HashMap<>();
                map1.put("reply",c);
                //查询用户姓名
                User user = new User();
                user.setId(c.getUserId());
                user = userMapper.check(user);
                map1.put("user",user);

                //根据每条评论的回复，得到点赞的总数，和当前用户是否点赞。
                LikeVO likeVO = likeService.commentQueryLike(c.getId(), userId);
                map1.put("likeVO",likeVO);

                replyCommentsVO.add(map1);
            }

            //进行查询当前楼主评论的用户名
            User user = new User();
            user.setId(con.getUserId());
            User check = userMapper.check(user);
            map.put("comment",con);  //设置当前的楼主评论内容
            map.put("user",check);   //设置当前用户信息
            map.put("replys",replyCommentsVO);  //设置当前回复评论信息。
            map.put("replyNums",replyComments.size());
            //查询当前帖子的点赞
            //得到转化为在redis中存储的key值
            LikeVO likeVO = likeService.commentQueryLike(con.getId(), userId);
            map.put("likeVO",likeVO);

            commentListVO.add(map);
        }

        //结果放入到返回结果中。
        PostAndCommentVO postAndCommentVO = new PostAndCommentVO();
        postAndCommentVO.setTotal(page.getTotal());
        postAndCommentVO.setCommentListVO(commentListVO);

        return postAndCommentVO;
    }

    /**
     * 添加评论的方法。
     * @param comment
     */
    @Override
    @Transactional
    public void add(Comment comment) {
        //为评论创建当前回复的时间。
        comment.setCreateTime(LocalDateTime.now());

        //1、先将评论添加进入评论表。
        commentMapper.add(comment);
        //把新添加的评论消息，作为系统通知发送到用户中。

        System.out.println("想要操作的用户id为：" + comment.getTargetId());

        if(comment.getTargetId() == 0){  //代表是给系统帖子发送的评论。
            eventMsgDomain.setFromId(1);  //代表当前消息是系统发送的。
            eventMsgDomain.setId(comment.getEntityId());
            eventMsgDomain.setConversationId("comment");
            eventMsgDomain.setEntity_type(2);
            eventMsgDomain.setUserid(comment.getUserId());
            eventMsgDomain.setOperate_type("发布");

            String msg = JSON.toJSONString(eventMsgDomain);

            systemMsgProducer.producer(msg);
        }
        else {  //代表是回复评论
            eventMsgDomain.setFromId(1);  //代表当前消息是系统发送的。
            eventMsgDomain.setId(comment.getEntityId());
            eventMsgDomain.setConversationId("comment");
            eventMsgDomain.setEntity_type(2);
            eventMsgDomain.setUserid(comment.getUserId());
            eventMsgDomain.setOperate_type("回复");
            eventMsgDomain.setToId(comment.getTargetId());

            String msg = JSON.toJSONString(eventMsgDomain);

            systemMsgProducer.producer(msg);
        }

        //2、然后将帖子的数量进行更改。
        //根据帖子的id，更改帖子的数量
        discussPostMapper.updateNum(comment.getEntityId());

        //对当前进行加精的帖子进行热度分数更新，把当前的帖子id保存到redis中，然后使用定时线程池，处理业务,完成帖子的热度更新操作。
        //使用redis的set数据结构保存，所有要更新热度的帖子id。
        //点赞，评论，加精都会让帖子的热度更新。
        //得到保存到redis中的key
        String scoreKey = RedisKeyUtil.scoreInit();
        redisTemplate.opsForSet().add(scoreKey,comment.getEntityId());

    }

    /**
     * 根据id查询评论的详细信息
     * @param comment
     * @return
     */
    @Override
    public Comment queryPostByPostId(Comment comment) {
        comment = commentMapper.queryPostByPostId(comment);
        return comment;
    }

    /**
     * 查询当前用户的所有回复
     * @param page
     * @param pagenum
     */
    @Override
    public CommentVO queryCommentByUser(Integer page, Integer pagenum,Integer userId) {

        PageHelper.startPage(page,pagenum);
        Page<Comment> page1 = commentMapper.queryCommentByUser(userId);
        List<Comment> result = page1.getResult();
        List<CommentAndPost> list = new ArrayList<>();
        for (Comment comment : result) {
            CommentAndPost commentAndPost = new CommentAndPost();
            //查询回复对应的帖子的标题
            DiscussPost discussPost = new DiscussPost();
            discussPost.setId(comment.getEntityId());
            discussPost = discussPostMapper.queryPostByPostId(discussPost);
            commentAndPost.setTitle(discussPost.getTitle());
            commentAndPost.setPostUserId(Integer.parseInt(discussPost.getUserId()));
            BeanUtils.copyProperties(comment,commentAndPost);
            list.add(commentAndPost);
        }
        //保存返回给客户端的数据
        CommentVO commentVO = new CommentVO();
        commentVO.setCurPage(page);
        commentVO.setTotal(page1.getTotal());
        commentVO.setData(list);

        return commentVO;
    }

    /**
     * 当前删除帖子的时候，一并把评论删除
     * @param postId
     */
    @Override
    public void delete(Integer postId) {
        commentMapper.delete(postId);
    }
}
